﻿using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using SLControlLibrary.Resources.Controls.Calendar.OutlookCalendar.Common;

namespace SLControlLibrary.Resources.Controls.Calendar.OutlookCalendar
{
    public class AppointmentItemsPanel : Panel
    {
        #region Variables

        public ucItemsControl Owner = null;
        private double ContentHeight = 22;

        #endregion Variables

        #region Methods

        #region ArrangeOverride

        protected override Size ArrangeOverride(Size finalSize)
        {
            for (int i = 0; i < this.Children.Count; i++)
            {
                double y = 0;
                double x = 0;
                Size ChildSize = new Size();

                UIElement child = (UIElement)this.Children[i];

                if (child.GetType() == typeof(ucAppointmentItem))
                {
                    ucAppointmentItem item = (ucAppointmentItem)child;

                    int count = 1;
                    int position = 0;
                    CalculateItemsInSlot(item, out count, out position);

                    ChildSize = CalculateHeightWidth(finalSize, item.StartDate, item.EndDate, item.StartTime, item.EndTime, Owner.Owner.TimeSlotsPerHour, count);
                    switch (Owner.Owner.CurrentDateView)
                    {
                        case Enumerations.DateView.Day:
                            x = ChildSize.Width * position;
                            break;
                        case Enumerations.DateView.WorkWeek:
                        case Enumerations.DateView.FullWeek:
                            x = CalculateX(Owner.Owner.CurrentDate, item.StartDate, ChildSize.Width, count, position);
                            break;
                        case Enumerations.DateView.Month:
                            break;
                    }

                    y = CalculateY(item.StartTime, Owner.Owner.TimeSlotsPerHour, Owner.Owner.HoursPerDay);
                }

                child.Arrange(new Rect(x, y, ChildSize.Width, ChildSize.Height));
            }

            return base.ArrangeOverride(finalSize);
        }

        #endregion ArrangeOverride

        #region MeasureOverride

        protected override Size MeasureOverride(Size availableSize)
        {
            foreach (UIElement child in this.Children)
            {
                if (child != null && child.GetType() == typeof(ucAppointmentItem))
                {
                    ucAppointmentItem item = (ucAppointmentItem)child;

                    int count = 1;
                    int position = 0;
                    CalculateItemsInSlot(item, out count, out position);

                    Size tmpSize = CalculateHeightWidth(availableSize, item.StartDate, item.EndDate, item.StartTime, item.EndTime, Owner.Owner.TimeSlotsPerHour, count);
                    child.Measure(tmpSize);
                }
            }

            return new Size(availableSize.Width, (((24 / (int)Owner.Owner.HoursPerDay) * (60 / (int)Owner.Owner.TimeSlotsPerHour) * 22) + 8));
        }

        #endregion MeasureOverride

        #region CalculateHeightWidth

        private void CalculateItemsInSlot(ucAppointmentItem item, out int count, out int position)
        {
            var appointmentItems = this.Children.Select(c => c as ucAppointmentItem).Where(c => c.GetType() == typeof(ucAppointmentItem));
            var intersectingAppointmentItems = appointmentItems.Select(c => c as ucAppointmentItem)
                                           .Where(c => (c.StartDate <= item.StartDate && (c.EndDate >= item.EndDate || c.EndDate > item.StartDate)) ||
                                           (item.StartDate <= c.StartDate && (item.EndDate >= c.EndDate || item.EndDate > c.StartDate)));
            count = intersectingAppointmentItems.Count();
            position = 0;
            for (int i = 0; i < intersectingAppointmentItems.Count(); i++)
            {
                if (intersectingAppointmentItems.ElementAt(i) == item)
                {
                    position = i;
                }
            }
        }

        private Size CalculateHeightWidth(Size AvailableSize, DateTime StartDate, DateTime EndDate, TimeSpan StartTime, TimeSpan EndTime, SLControlLibrary.Resources.Common.Enumerations.TimeSlotsPerHour TimeSlots, int count)
        {
            double width = 0;
            double height = 0;
            double minuteHeight = 0;
            minuteHeight += (StartTime.Minutes / (int)TimeSlots) * ContentHeight;

            if (EndTime.Hours - StartTime.Hours != 0)
                height = ((EndTime.Hours - StartTime.Hours) * ContentHeight) * (60 / (int)TimeSlots);

            if (StartTime.Minutes > 0)
                height -= minuteHeight;

            minuteHeight = (EndTime.Minutes / (int)TimeSlots) * ContentHeight;

            height += minuteHeight;

            switch (Owner.Owner.CurrentDateView)
            {
                case Enumerations.DateView.Day:
                    width = AvailableSize.Width / count;
                    break;
                case Enumerations.DateView.WorkWeek:
                    width = AvailableSize.Width / 5 / count;
                    break;
                case Enumerations.DateView.FullWeek:
                    width = AvailableSize.Width / 7 / count;
                    break;
                case Enumerations.DateView.Month:
                    height = 0;
                    break;
            }

            return new Size(width, height);
        }

        #endregion CalculateHeightWidth

        #region CalculateX

        private double CalculateX(DateTime CurrentDate, DateTime StartDate, double width, int count, int position)
        {
            DateTime _MondaysDate = CurrentDate.AddDays((int)System.DayOfWeek.Monday - (int)CurrentDate.DayOfWeek);

            TimeSpan tmpDateDiff = StartDate - _MondaysDate;
            return (double)tmpDateDiff.Days * width * count + width * position;
        }

        #endregion CalculateX

        #region CalculateY

        private double CalculateY(TimeSpan StartTime, SLControlLibrary.Resources.Common.Enumerations.TimeSlotsPerHour TimeSlots, SLControlLibrary.Resources.Common.Enumerations.HoursPerDay HoursPerDay)
        {
            return (double)(StartTime.Hours * ContentHeight) * (60 / (int)TimeSlots) + ((StartTime.Minutes / (int)TimeSlots) * ContentHeight);
        }

        #endregion CalculateY

        #endregion Methods
    }
}